home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 2000
/
MacHack 2000.toast
/
pc
/
The Hacks
/
Close Window Thing
/
Close Window Thing.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-06-23
|
24KB
|
647 lines
#include <Resources.h>
#include <Icons.h>
#include <OSUtils.h>
#include <Sound.h>
#include <Quickdraw.h>
#include <QDOffscreen.h>
typedef struct
{
short effectType;
short speed;
} Preferences;
#define kMinimumSystemVersion 0x00000700
enum
{
uppTrackGoAwayProcInfo = kPascalStackBased
| RESULT_SIZE( SIZE_CODE( sizeof( Boolean ) ) )
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Point)))
};
enum
{
uppMenuSelectProcInfo = kPascalStackBased
| RESULT_SIZE( SIZE_CODE( sizeof( long ) ) )
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(Point)))
};
enum
{
uppGetNextEventProcInfo = kPascalStackBased
| RESULT_SIZE( SIZE_CODE( sizeof( Boolean ) ) )
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(EventRecord *)))
};
pascal Boolean NewTrackGoAway( WindowPtr theWindow, Point thePoint );
pascal long NewMenuSelect( Point startPt );
pascal Boolean NewGetNextEvent( short eventMask, EventRecord *theEvent );
Boolean IsFinderFrontProcess( void );
void IsCloseWindow( long theChoice );
void DoLenCloseWindowThing( WindowPtr theWindow );
void DoJoshCloseWindowThing( WindowPtr theWindow );
void LoadPrefs( Preferences *prefs );
void NewPrefs( Preferences *prefs, FSSpec spec, short *prefsFRefNum );
UniversalProcPtr gOldTrackGoAway = nil, gNewTrackGoAway;
UniversalProcPtr gOldMenuSelect = nil, gNewMenuSelect;
UniversalProcPtr gOldGetNextEvent = nil, gNewGetNextEvent;
QDGlobals qd;
Preferences **prefsHan, prefs;
void main(void)
{
OSErr err = noErr;
THz oldZone;
// Save the old zone and set the current zone to the system zone
oldZone = GetZone();
SetZone( SystemZone() );
// Preserve our code in memory
DetachResource(GetResource('INIT', 0));
// Get the address of the TrackGoAway trap
gOldTrackGoAway = GetToolTrapAddress( _TrackGoAway );
// Create a routine descriptor for our new TrackGoAway function
gNewTrackGoAway = NewRoutineDescriptor( (ProcPtr) &NewTrackGoAway, uppTrackGoAwayProcInfo,kPowerPCISA);
// Patch our function into the trap table
SetToolTrapAddress( gNewTrackGoAway, _TrackGoAway );
// Get the address of the MenuSelect trap
gOldMenuSelect = GetToolTrapAddress( _MenuSelect );
// Create a routine descriptor for our new MenuSelect function
gNewMenuSelect = NewRoutineDescriptor( (ProcPtr)&NewMenuSelect, uppMenuSelectProcInfo,kPowerPCISA);
// Patch our function into the trap table
SetToolTrapAddress( gNewMenuSelect, _MenuSelect );
// Get the address of the GetNextEvent trap
gOldGetNextEvent = GetToolTrapAddress( _GetNextEvent );
// Create a routine descriptor for our new GetNextEvent function
gNewGetNextEvent = NewRoutineDescriptor( (ProcPtr)&NewGetNextEvent, uppGetNextEventProcInfo, kPowerPCISA );
// Patch our function into the trap table
SetToolTrapAddress( gNewGetNextEvent, _GetNextEvent );
LoadPrefs( &prefs );
// Restore the old zone
SetZone(oldZone);
}
pascal Boolean NewTrackGoAway( WindowPtr theWindow, Point thePoint )
{
Boolean result;
// Head Patch
result = CallUniversalProc( gOldTrackGoAway, uppTrackGoAwayProcInfo, theWindow, thePoint );
// Only run if the Finder is the front process and user wants to close the window
if ( IsFinderFrontProcess() && result )
{
// Do our pre-closing show
LoadPrefs( &prefs );
if ( prefs.effectType == 1 )
DoLenCloseWindowThing( theWindow );
else if ( prefs.effectType == 2 )
DoJoshCloseWindowThing( theWindow );
}
return result;
}
pascal long NewMenuSelect( Point startPt )
{
long result;
// Head Patch
result = CallUniversalProc( gOldMenuSelect, uppMenuSelectProcInfo, startPt );
// Only run if the Finder is the front process
if ( IsFinderFrontProcess() )
{
// Dis the user choose "Close Window"?
IsCloseWindow( result );
}
return result;
}
pascal Boolean NewGetNextEvent( short eventMask, EventRecord *theEvent )
{
long result;
// Head Patch
result = CallUniversalProc( gOldGetNextEvent, uppGetNextEventProcInfo, eventMask, theEvent );
// Only run if the Finder is the front proccess
if ( IsFinderFrontProcess() )
{
// Did the user choose "Close Window?"
if ( theEvent->what == keyDown )
{
short theChar;
theChar = theEvent->message & charCodeMask;
if ( ( theEvent->modifiers & cmdKey ) != 0 )
{
if ( theEvent->what != autoKey )
{
if ( theChar == 'w' )
{
LoadPrefs( &prefs );
if ( prefs.effectType == 1 )
DoLenCloseWindowThing( LMGetWindowList() );
else if ( prefs.effectType == 2 )
DoJoshCloseWindowThing( LMGetWindowList() );
}
}
}
}
}
return result;
}
Boolean IsFinderFrontProcess( void )
{
ProcessSerialNumber finderPSN, curPSN;
ProcessInfoRec theProc;
Boolean sameProcess;
finderPSN.highLongOfPSN = 0;
finderPSN.lowLongOfPSN = kNoProcess;
theProc.processInfoLength = sizeof(ProcessInfoRec);
theProc.processName = nil;
theProc.processAppSpec = nil;
theProc.processLocation = nil;
// Check every process until we locate the Finder
while (true)
{
GetNextProcess( &finderPSN );
GetProcessInformation( &finderPSN, &theProc );
if ( ( theProc.processType == 'FNDR' ) && ( theProc.processSignature == 'MACS' ) )
break;
}
// Get the Process Serial Number of the front process
GetFrontProcess( &curPSN );
// Compare it to the Finder's process serial number
SameProcess( &finderPSN, &curPSN, &sameProcess );
return sameProcess;
}
// Does the user want to close the window?
void IsCloseWindow( long theChoice )
{
MenuHandle menuHandle;
Str255 theString;
short theMenu, theMenuItem;
theMenu = HiWord( theChoice );
theMenuItem = LoWord( theChoice );
// Get a handle to the chosen menu
menuHandle = GetMenuHandle( theMenu );
// Get the name of the item chosen
GetMenuItemText( menuHandle, theMenuItem, theString );
// Is the name of the item chosen "Close Window" so we can do our pre-closing show?
if ( EqualString( theString, "\pClose Window", false, false ) )
{
LoadPrefs( &prefs );
if ( prefs.effectType == 1 )
DoLenCloseWindowThing( LMGetWindowList() );
else if ( prefs.effectType == 2 )
DoJoshCloseWindowThing( LMGetWindowList() );
}
}
void DoLenCloseWindowThing( WindowPtr theWindow )
{
WindowPtr savePort;
GrafPtr theScreen;
GDHandle saveDevice;
GWorldPtr windowWorld, backgroundWorld, scrapWorld,
theOffScreen0, theOffScreen1, theOffScreen2, theOffScreen3,
theOffScreen4, theOffScreen5, theOffScreen6, theOffScreen7;
Rect screenRect, globalWindow, localWindow, centerWindow, globalScrap, localScrap;
Rect windowRect00, windowRect01, windowRect02, windowRect03,
windowRect10, windowRect11, windowRect12, windowRect13,
locWindowRect00, locWindowRect01, locWindowRect02, locWindowRect03,
locWindowRect10, locWindowRect11, locWindowRect12, locWindowRect13,
locWindowSRect00, locWindowSRect01, locWindowSRect02, locWindowSRect03,
locWindowSRect10, locWindowSRect11, locWindowSRect12, locWindowSRect13;
Str255 name;
GetWTitle( theWindow, name );
if ( EqualString( name, "\pDesktop", false, false ) )
return;
// Get the Color Window Manager's port (To draw to the screen)
GetCWMgrPort( &(CGrafPort *)theScreen );
// Save the current GWorld
GetGWorld( &(CGrafPtr)savePort, &saveDevice );
// Set the QuickDraw port to the window to play with
SetPort( theWindow );
// Calculate our rectangles
screenRect = theScreen->portRect;
OffsetRect( &screenRect, -screenRect.left, -screenRect.top );
localWindow = theWindow->portRect;
OffsetRect( &localWindow, -localWindow.left, -localWindow.top );
globalWindow = localWindow;
localWindow.bottom += 27;
localWindow.right += 11;
LocalToGlobal( (Point *)&globalWindow );
LocalToGlobal( (Point *)&globalWindow.bottom );
globalWindow.top -= 22;
globalWindow.left -= 6;
globalWindow.bottom += 7;
globalWindow.right += 7;
localScrap = localWindow;
localScrap.right += 10;
centerWindow = localScrap;
centerWindow.right -= 10;
centerWindow.left += 10;
globalScrap = globalWindow;
globalScrap.left -= 10;
globalScrap.right += 10;
// Create our three offscreen graphics worlds
NewGWorld( &windowWorld, 0, &localWindow, 0, 0, useTempMem );
NewGWorld( &backgroundWorld, 0, &screenRect, 0, 0, useTempMem );
NewGWorld( &scrapWorld, 0, &localScrap, 0, 0, useTempMem );
// Copy the window we're playing with into its offscreen world
SetGWorld( windowWorld, NULL );
CopyBits( &theScreen->portBits, &((GrafPtr)windowWorld)->portBits, &globalWindow, &localWindow, srcCopy, NULL );
// Hide our window and take a short break
HideWindow( theWindow );
GetNextEvent( nil, nil );
// Copy the screen to the background world again
SetGWorld( backgroundWorld, NULL );
CopyBits( &theScreen->portBits, &((GrafPtr)backgroundWorld)->portBits, &screenRect, &screenRect, srcCopy, NULL );
// Set the Graphics World to an offscreen world
SetGWorld( scrapWorld, NULL );
//Works
windowRect00.top = globalWindow.top;
windowRect00.left = (globalWindow.left);
windowRect00.bottom = ((localWindow.bottom / 2) + globalWindow.top);
windowRect00.right = ((localWindow.right / 4) + globalWindow.left);
//Works
windowRect01.top = globalWindow.top;
windowRect01.left = windowRect00.right;
windowRect01.bottom = ((localWindow.bottom / 2) + globalWindow.top);
windowRect01.right = ((localWindow.right / 2) + globalWindow.left);
//Works
windowRect02.top = globalWindow.top;
windowRect02.left = windowRect01.right;
windowRect02.bottom = ((localWindow.bottom / 2) + globalWindow.top);
windowRect02.right = (((localWindow.right / 4) * 3) + globalWindow.left);
//Works
windowRect03.top = globalWindow.top;
windowRect03.left = windowRect02.right;
windowRect03.bottom = ((localWindow.bottom / 2) + globalWindow.top);
windowRect03.right = globalWindow.right;
//Works
windowRect10.top = ((localWindow.bottom / 2) + globalWindow.top);
windowRect10.left = globalWindow.left;
windowRect10.bottom = globalWindow.bottom - 1;
windowRect10.right = ((localWindow.right / 4) + globalWindow.left);
//Works
windowRect11.top = ((localWindow.bottom / 2) + globalWindow.top);
windowRect11.left = windowRect10.right;
windowRect11.bottom = globalWindow.bottom;
windowRect11.right = ((localWindow.right / 2) + globalWindow.left);
//Works
windowRect12.top = ((localWindow.bottom / 2) + globalWindow.top);
windowRect12.left = windowRect11.right;
windowRect12.bottom = globalWindow.bottom;
windowRect12.right = (((localWindow.right / 4) * 3) + globalWindow.left);
//Works
windowRect13.top = (( localWindow.bottom / 2 ) + globalWindow.top);
windowRect13.left = windowRect12.right;
windowRect13.bottom = globalWindow.bottom - 1;
windowRect13.right = globalWindow.right;
NewGWorld( &theOffScreen0, 0, &windowRect00, 0, 0, useTempMem );
NewGWorld( &theOffScreen1, 0, &windowRect01, 0, 0, useTempMem );
NewGWorld( &theOffScreen2, 0, &windowRect02, 0, 0, useTempMem );
NewGWorld( &theOffScreen3, 0, &windowRect03, 0, 0, useTempMem );
NewGWorld( &theOffScreen4, 0, &windowRect10, 0, 0, useTempMem );
NewGWorld( &theOffScreen5, 0, &windowRect11, 0, 0, useTempMem );
NewGWorld( &theOffScreen6, 0, &windowRect12, 0, 0, useTempMem );
NewGWorld( &theOffScreen7, 0, &windowRect13, 0, 0, useTempMem );
locWindowRect00 = theOffScreen0->portRect;
locWindowSRect00 = theOffScreen0->portRect;
//theOffScreen0->portRect.bottom += 2;
//theOffScreen0->portRect.right += 3;
OffsetRect( &locWindowRect00, -3, -2 );
locWindowRect01 = theOffScreen1->portRect;
locWindowSRect01 = theOffScreen1->portRect;
//theOffScreen1->portRect.bottom += 3;
//theOffScreen1->portRect.right += 2;
OffsetRect( &locWindowRect01, -2, -3 );
locWindowRect02 = theOffScreen2->portRect;
locWindowSRect02 = theOffScreen2->portRect;
//theOffScreen2->portRect.bottom += 3;
//theOffScreen2->portRect.left -= 2;
OffsetRect( &locWindowRect02, 2, -3 );
locWindowRect03 = theOffScreen3->portRect;
locWindowSRect03 = theOffScreen3->portRect;
//theOffScreen3->portRect.bottom += 2;
//theOffScreen3->portRect.left -= 3;
OffsetRect( &locWindowRect03, 3, -2 );
locWindowRect10 = theOffScreen4->portRect;
locWindowSRect10 = theOffScreen4->portRect;
//theOffScreen4->portRect.top -= 2;
//theOffScreen4->portRect.right += 3;
OffsetRect( &locWindowRect10, -3, 2 );
locWindowRect11 = theOffScreen5->portRect;
locWindowSRect11 = theOffScreen5->portRect;
//theOffScreen5->portRect.top -= 3;
//theOffScreen5->portRect.right += 2;
OffsetRect( &locWindowRect11, -2, 3 );
locWindowRect12 = theOffScreen6->portRect;
locWindowSRect12 = theOffScreen6->portRect;
//theOffScreen6->portRect.top -= 3;
//theOffScreen6->portRect.left -= 2;
OffsetRect( &locWindowRect12, 2, 3 );
locWindowRect13 = theOffScreen7->portRect;
locWindowSRect13 = theOffScreen7->portRect;
//theOffScreen7->portRect.top -= 2;
//theOffScreen7->portRect.left -= 3;
OffsetRect( &locWindowRect13, 3, 2 );
OffsetRect( &locWindowSRect01, locWindowSRect00.right, NULL );
OffsetRect( &locWindowSRect02, locWindowSRect01.right, NULL );
OffsetRect( &locWindowSRect03, locWindowSRect02.right, NULL );
OffsetRect( &locWindowSRect10, NULL, locWindowSRect00.bottom );
OffsetRect( &locWindowSRect11, locWindowSRect10.right, locWindowSRect01.bottom );
OffsetRect( &locWindowSRect12, locWindowSRect11.right, locWindowSRect02.bottom );
OffsetRect( &locWindowSRect13, locWindowSRect12.right, locWindowSRect03.bottom );
windowRect00.bottom += 2;
windowRect00.right += 3;
windowRect01.bottom += 3;
windowRect01.right += 2;
windowRect02.bottom += 3;
windowRect02.left -= 2;
windowRect03.bottom += 2;
windowRect03.left -= 3;
windowRect10.top -= 2;
windowRect10.right += 3;
windowRect11.top -= 3;
windowRect11.right += 2;
windowRect12.top -= 3;
windowRect12.left -= 2;
windowRect13.top -= 2;
windowRect13.left -= 3;
UpdateGWorld(&theOffScreen0, 0, &windowRect00, 0, 0, useTempMem);
UpdateGWorld(&theOffScreen1, 0, &windowRect01, 0, 0, useTempMem);
UpdateGWorld(&theOffScreen2, 0, &windowRect02, 0, 0, useTempMem);
UpdateGWorld(&theOffScreen3, 0, &windowRect03, 0, 0, useTempMem);
UpdateGWorld(&theOffScreen4, 0, &windowRect10, 0, 0, useTempMem);
UpdateGWorld(&theOffScreen5, 0, &windowRect11, 0, 0, useTempMem);
UpdateGWorld(&theOffScreen6, 0, &windowRect12, 0, 0, useTempMem);
UpdateGWorld(&theOffScreen7, 0, &windowRect13, 0, 0, useTempMem);
do {
// Copy the background into theOffScreen scrap world
CopyBits( &((GrafPtr)backgroundWorld)->portBits, &((GrafPtr)theOffScreen0)->portBits, &windowRect00, &theOffScreen0->portRect, srcCopy, NULL );
CopyBits( &((GrafPtr)backgroundWorld)->portBits, &((GrafPtr)theOffScreen1)->portBits, &windowRect01, &theOffScreen1->portRect, srcCopy, NULL );
CopyBits( &((GrafPtr)backgroundWorld)->portBits, &((GrafPtr)theOffScreen2)->portBits, &windowRect02, &theOffScreen2->portRect, srcCopy, NULL );
CopyBits( &((GrafPtr)backgroundWorld)->portBits, &((GrafPtr)theOffScreen3)->portBits, &windowRect03, &theOffScreen3->portRect, srcCopy, NULL );
CopyBits( &((GrafPtr)backgroundWorld)->portBits, &((GrafPtr)theOffScreen4)->portBits, &windowRect10, &theOffScreen4->portRect, srcCopy, NULL );
CopyBits( &((GrafPtr)backgroundWorld)->portBits, &((GrafPtr)theOffScreen5)->portBits, &windowRect11, &theOffScreen5->portRect, srcCopy, NULL );
CopyBits( &((GrafPtr)backgroundWorld)->portBits, &((GrafPtr)theOffScreen6)->portBits, &windowRect12, &theOffScreen6->portRect, srcCopy, NULL );
CopyBits( &((GrafPtr)backgroundWorld)->portBits, &((GrafPtr)theOffScreen7)->portBits, &windowRect13, &theOffScreen7->portRect, srcCopy, NULL );
// Copy the window into the scrap world
CopyBits( &((GrafPtr)windowWorld)->portBits, &((GrafPtr)theOffScreen0)->portBits, &locWindowSRect00, &locWindowRect00, srcCopy, NULL );
CopyBits( &((GrafPtr)windowWorld)->portBits, &((GrafPtr)theOffScreen1)->portBits, &locWindowSRect01, &locWindowRect01, srcCopy, NULL );
CopyBits( &((GrafPtr)windowWorld)->portBits, &((GrafPtr)theOffScreen2)->portBits, &locWindowSRect02, &locWindowRect02, srcCopy, NULL );
CopyBits( &((GrafPtr)windowWorld)->portBits, &((GrafPtr)theOffScreen3)->portBits, &locWindowSRect03, &locWindowRect03, srcCopy, NULL );
CopyBits( &((GrafPtr)windowWorld)->portBits, &((GrafPtr)theOffScreen4)->portBits, &locWindowSRect10, &locWindowRect10, srcCopy, NULL );
CopyBits( &((GrafPtr)windowWorld)->portBits, &((GrafPtr)theOffScreen5)->portBits, &locWindowSRect11, &locWindowRect11, srcCopy, NULL );
CopyBits( &((GrafPtr)windowWorld)->portBits, &((GrafPtr)theOffScreen6)->portBits, &locWindowSRect12, &locWindowRect12, srcCopy, NULL );
CopyBits( &((GrafPtr)windowWorld)->portBits, &((GrafPtr)theOffScreen7)->portBits, &locWindowSRect13, &locWindowRect13, srcCopy, NULL );
// Copy the contents of the scrap world to the screen
CopyBits( &((GrafPtr)theOffScreen0)->portBits, &((GrafPtr)theScreen)->portBits, &theOffScreen0->portRect, &windowRect00, srcCopy, NULL );
CopyBits( &((GrafPtr)theOffScreen1)->portBits, &((GrafPtr)theScreen)->portBits, &theOffScreen1->portRect, &windowRect01, srcCopy, NULL );
CopyBits( &((GrafPtr)theOffScreen2)->portBits, &((GrafPtr)theScreen)->portBits, &theOffScreen2->portRect, &windowRect02, srcCopy, NULL );
CopyBits( &((GrafPtr)theOffScreen3)->portBits, &((GrafPtr)theScreen)->portBits, &theOffScreen3->portRect, &windowRect03, srcCopy, NULL );
CopyBits( &((GrafPtr)theOffScreen4)->portBits, &((GrafPtr)theScreen)->portBits, &theOffScreen4->portRect, &windowRect10, srcCopy, NULL );
CopyBits( &((GrafPtr)theOffScreen5)->portBits, &((GrafPtr)theScreen)->portBits, &theOffScreen5->portRect, &windowRect11, srcCopy, NULL );
CopyBits( &((GrafPtr)theOffScreen6)->portBits, &((GrafPtr)theScreen)->portBits, &theOffScreen6->portRect, &windowRect12, srcCopy, NULL );
CopyBits( &((GrafPtr)theOffScreen7)->portBits, &((GrafPtr)theScreen)->portBits, &theOffScreen7->portRect, &windowRect13, srcCopy, NULL );
OffsetRect( &windowRect00, -3, -2);
OffsetRect( &windowRect01, -2, -3);
OffsetRect( &windowRect02, 2, -3);
OffsetRect( &windowRect03, 3, -2);
OffsetRect( &windowRect10, -3, 2);
OffsetRect( &windowRect11, -2, 3);
OffsetRect( &windowRect12, 2, 3);
OffsetRect( &windowRect13, 3, 2);
} while ( (windowRect00.right > 0) || (windowRect01.bottom > 0) || (windowRect02.bottom > 0) || (windowRect03.left < theScreen->portRect.right) ||
(windowRect10.right > 0) || (windowRect11.top < theScreen->portRect.bottom) || (windowRect12.top < theScreen->portRect.bottom) ||
(windowRect13.left < theScreen->portRect.right) );
// Clean up by setting the screen to its origional state
CopyBits( &((GrafPtr)backgroundWorld)->portBits, &theScreen->portBits, &screenRect, &screenRect, srcCopy, NULL );
// Kill our graphics worlds
DisposeGWorld( windowWorld );
DisposeGWorld( backgroundWorld );
DisposeGWorld( scrapWorld );
DisposeGWorld( theOffScreen0 );
DisposeGWorld( theOffScreen1 );
DisposeGWorld( theOffScreen2 );
DisposeGWorld( theOffScreen3 );
DisposeGWorld( theOffScreen4 );
DisposeGWorld( theOffScreen5 );
DisposeGWorld( theOffScreen6 );
DisposeGWorld( theOffScreen7 );
// Reset the previous state of QuickDraw
SetGWorld( (CGrafPtr)savePort, saveDevice );
}
void DoJoshCloseWindowThing( WindowPtr theWindow )
{
WindowPtr savePort;
GrafPtr theScreen;
GDHandle saveDevice;
GWorldPtr windowWorld, backgroundWorld, scrapWorld;
Rect screenRect, globalWindow, localWindow, centerWindow, localScrap, globalScrap;
Str255 name;
GetWTitle( theWindow, name );
if ( EqualString( name, "\pDesktop", false, false ) )
return;
// Get the Color Window Manager's port (To draw to the screen)
GetCWMgrPort( &(CGrafPort *)theScreen );
// Save the current GWorld
GetGWorld( &(CGrafPtr)savePort, &saveDevice );
// Set the QuickDraw port to the window to play with
SetPort( theWindow );
// Calculate our rectangles
screenRect = theScreen->portRect;
OffsetRect( &screenRect, -screenRect.left, -screenRect.top );
localWindow = theWindow->portRect;
OffsetRect( &localWindow, -localWindow.left, -localWindow.top );
globalWindow = localWindow;
localWindow.bottom += 27;
localWindow.right += 11;
LocalToGlobal( (Point *)&globalWindow );
LocalToGlobal( (Point *)&globalWindow.bottom );
globalWindow.top -= 22;
globalWindow.left -= 6;
globalWindow.bottom += 7;
globalWindow.right += 7;
localScrap = localWindow;
localScrap.right += 10;
centerWindow = localScrap;
centerWindow.right -= 5 * prefs.speed;
centerWindow.left += 5 * prefs.speed;
globalScrap = globalWindow;
globalScrap.left -= 5 * prefs.speed;
globalScrap.right += 5 * prefs.speed;
// Create our three offscreen graphics worlds
NewGWorld( &windowWorld, 0, &localWindow, 0, 0, useTempMem );
NewGWorld( &backgroundWorld, 0, &screenRect, 0, 0, useTempMem );
NewGWorld( &scrapWorld, 0, &localScrap, 0, 0, useTempMem );
// Copy the window we're playing with into its offscreen world
SetGWorld( windowWorld, NULL );
CopyBits( &theScreen->portBits, &((GrafPtr)windowWorld)->portBits, &globalWindow, &localWindow, srcCopy, NULL );
// Hide our window and take a short break
HideWindow( theWindow );
GetNextEvent( nil, nil );
// Copy the screen to the background world
SetGWorld( backgroundWorld, NULL );
CopyBits( &theScreen->portBits, &((GrafPtr)backgroundWorld)->portBits, &screenRect, &screenRect, srcCopy, NULL );
// Set the Graphics World to an offscreen world
SetGWorld( scrapWorld, NULL );
do
{
// Copy the background into the scrap world
CopyBits( &((GrafPtr)backgroundWorld)->portBits, &((GrafPtr)scrapWorld)->portBits, &globalScrap, &localScrap, srcCopy, NULL );
// Copy the window into the scrap world
CopyBits( &((GrafPtr)windowWorld)->portBits, &((GrafPtr)scrapWorld)->portBits, &localWindow, ¢erWindow, srcCopy, NULL );
// Copy the contents of the scrap world to the screen
CopyBits( &((GrafPtr)scrapWorld)->portBits, &theScreen->portBits, &localScrap, &globalScrap, srcCopy, NULL );
// Update the rectangle for the next time through
globalScrap.left -= 5 * prefs.speed;
globalScrap.right -= 5 * prefs.speed;
}
while ( globalScrap.right > 0 );
// Clean up by setting the screen to its origional state
CopyBits( &((GrafPtr)backgroundWorld)->portBits, &theScreen->portBits, &screenRect, &screenRect, srcCopy, NULL );
// Kill our graphics worlds
DisposeGWorld( windowWorld );
DisposeGWorld( backgroundWorld );
DisposeGWorld( scrapWorld );
// Reset the previous state of QuickDraw
SetGWorld( (CGrafPtr)savePort, saveDevice );
}
void LoadPrefs( Preferences *prefs )
{
OSErr myErr;
FSSpec mySpec;
short myVRef, prefsFRefNum;
long myDirID;
myErr = FindFolder(0x8000, 'pref', false, &myVRef, &myDirID);
myErr = FSMakeFSSpec( myVRef, myDirID, "\pClose Window Thing Prefs", &mySpec );
if( myErr == fnfErr )
NewPrefs( prefs, mySpec, &prefsFRefNum );
prefsFRefNum = FSpOpenResFile( &mySpec,3 );
prefsHan = (Preferences **)GetResource( 'Pref',128 );
prefs->effectType = (**prefsHan).effectType;
prefs->speed = (**prefsHan).speed;
if ( prefsHan != nil )
ReleaseResource( (Handle)prefsHan );
if ( prefsFRefNum )
FSClose( prefsFRefNum );
}
void NewPrefs( Preferences *prefs, FSSpec spec, short *prefsFRefNum )
{
FSpCreateResFile( &spec, 'PEJ2', 'pref', -1 );
*prefsFRefNum = FSpOpenResFile( &spec, 3 );
prefs->effectType = 1;
prefs->speed = 1;
(Handle)prefsHan = NewHandle( sizeof( Preferences ) );
(**prefsHan).effectType = prefs->effectType;
(**prefsHan).speed = prefs->speed;
HLock( (Handle)prefsHan );
AddResource( (Handle)prefsHan, 'Pref', 128, "\pPrefs");
WriteResource( (Handle)prefsHan );
HUnlock( (Handle)prefsHan );
UpdateResFile( *prefsFRefNum );
}